﻿using System;
using System.Collections.Generic;
using Common.Interface;
using EntityFrameworkExtension.Interface;
using FRM.Messenger.Common.Helper;
using MainProcessor.MessageProcessor;
using NUnit.Framework;
using Rhino.Mocks;

namespace Test.Main.Processors
{
    [TestFixture]
    public class FundStaticProcessorTests 
    {
        private IValidateInput validateInput1;
        private IValidateInput validateInput2;
        private List<IValidateInput> validateInputs;

        private IContextProcessor extraction1;
        private IContextProcessor extraction2;
        private List<IContextProcessor> extractions;
        private BaseProcessor<IContextProcessor, IValidateInput> processor;
        private IEfContext efContext;

        [SetUp]
        public void SetUp()
        {

            validateInput1 = MockRepository.GenerateMock<IValidateInput>();
            validateInput2 = MockRepository.GenerateMock<IValidateInput>();
            validateInputs = new List<IValidateInput> { validateInput1, validateInput2 };
            extraction1 = MockRepository.GenerateMock<IContextProcessor>();
            extraction2 = MockRepository.GenerateMock<IContextProcessor>();
            extractions = new List<IContextProcessor> { extraction1, extraction2 };
            efContext = MockRepository.GenerateMock<IEfContext>();


            processor = new BaseProcessor<IContextProcessor, IValidateInput>(efContext, validateInputs, extractions);
        }

        [TearDown]
        public void TearDown()
        {
            validateInput1.VerifyAllExpectations();
            validateInput2.VerifyAllExpectations();
            extraction1.VerifyAllExpectations();
            extraction2.VerifyAllExpectations();
            efContext.VerifyAllExpectations();
        }

        [Test]
        public void ValidationErrorsShouldConcatenate()
        {
            const string errorString1 = "<Error>Big error happened here</Error>";
            const string errorString2 = "<Error>litle insignificant error here</Error>";
            validateInput1.Expect(x => x.Validate(null)).IgnoreArguments().Return(errorString1);
            validateInput2.Expect(x => x.Validate(null)).IgnoreArguments().Return(errorString2);

            processor.MessageProcess(ConstantXml.TestString);
        }

        [Test]
        public void ValidationErrorsShouldRunAllExtractions()
        {
            validateInput1.Expect(x => x.Validate(null)).IgnoreArguments().Return(String.Empty).Repeat.Once();
            validateInput2.Expect(x => x.Validate(null)).IgnoreArguments().Return(String.Empty).Repeat.Once();
            extraction1.Expect(x => x.ExtractXml(null)).IgnoreArguments();
            extraction2.Expect(x => x.ExtractXml(null)).IgnoreArguments();

            processor.MessageProcess(ConstantXml.TestString);
        }

        [Test]
        public void PersistWillCallPopulateEfOn()
        {
            efContext.Expect(x => x.Open(null, null)).IgnoreArguments().Return(efContext);
            extraction1.Expect(x => x.PopulateEf(efContext));
            extraction2.Expect(x => x.PopulateEf(efContext));
            efContext.Expect(x => x.SaveChanges());

            processor.Persist();
        }

       
    }
}
